/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;



/**
java程式和資料庫之間，最花資源的是建立和關閉資料流，而執行sql指令只花一小部份資源
因此產生了Connection pool的機制
 */
/**
到Tomcat官網找自己版本的Documentation=>  JNDI Resources告訴你如何設定，在頁面找到JDBC Data Sources
=>  下面的  4. Configure Tomcat's Resource Factory  的程式碼貼到Configuration Files裡的context.xml做設定
* 
=>  下面的  3. Code Your Application's Use Of This Resource  的程式碼貼到自己撰寫的java DAO程式並稍作修改
 */


//import的資料都是javax.naming、javax.sql，不要import錯誤
public class BaseDAO {
    
    //驅動程式只需要載入一次，所以放在此區塊
    static{
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    public Connection getConnection() throws Exception{     //要丟出例外
        Context initCtx = new InitialContext();
        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        DataSource ds = (DataSource)
        envCtx.lookup("jdbc/javaDB");               //連線到context.xml的name

        Connection conn = ds.getConnection();       //取得連線
        return conn;
    }
    
    //執行sql的新增、修改、刪除
    public int modify(String sql, String[] ary){
        int x = 0;
        
        //要用try-catch包住，在Jsp程式會自動幫你做，在java要自己做
        //要使用自動關閉資源
        try(Connection con = this.getConnection();          //從自己寫的方法取得連線
            PreparedStatement ps = con.prepareStatement(sql);){
            
            for(int i = 0; i < ary.length; i++){
                ps.setString(i + 1, ary[i]);
            }
            x = ps.executeUpdate();             //用來新增、修改、刪除
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return x;
    }
    
    //執行sql的查詢
    public ArrayList query(String sql, String ary[]){
        
        ArrayList list = new ArrayList();
        
        try(Connection con = this.getConnection();          //從自己寫的方法取得連線
            PreparedStatement ps = con.prepareStatement(sql);){
            
            for(int i = 0; i < ary.length; i++){
                ps.setString(i + 1, ary[i]);
            }
            ResultSet rs = ps.executeQuery();           //ResultSet就像是報表
            ResultSetMetaData meta = rs.getMetaData();  //ResultSetMetaData會有ResultSet裡面的一些資訊
            int cols = meta.getColumnCount();           //取得ResultSet的欄位數
            while(rs.next()){
                HashMap map = new HashMap();
                for(int i = 1; i <= cols; i++){     //一列的資料放在一個map
                    map.put(meta.getColumnName(i), rs.getString(i));
                }
                list.add(map);
            }
            rs.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return list;
    }
}
